import { message } from "antd";
import axios, { type AxiosRequestConfig, type AxiosResponse } from "axios";
import { getToken, removeToken } from "./auth";

const http = axios.create({
  baseURL: `${import.meta.env.VITE_API_BASE_URL}/api`,
  timeout: 10000,
});

// 请求拦截器 - 添加token
http.interceptors.request.use((config) => {
  const token = getToken();
  if (token) {
    config.headers = config.headers || {};
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 响应拦截器 - 统一错误处理
http.interceptors.response.use(
  (response: AxiosResponse) => {
    // 处理业务逻辑错误
    if (response.data?.code !== 0 && response.data?.message) {
      message.error(response.data.message);
      return Promise.reject(response.data);
    }
    return response.data.data; // 直接返回response.data
  },
  (error) => {
    // 网络错误处理
    if (!error.response) {
      message.error("网络错误，请检查网络连接");
      return Promise.reject(error);
    }

    // HTTP状态码错误处理
    switch (error.response.status) {
      case 401:
        removeToken();
        window.location.href = "/login";
        message.error("登录已过期，请重新登录");
        break;
      case 403:
        message.error("无权限访问");
        break;
      case 404:
        message.error("请求资源不存在");
        break;
      case 500:
        message.error("服务器内部错误");
        break;
      default:
        message.error(error.response.data?.message || "请求失败");
    }

    return Promise.reject(error);
  },
);

// 封装带类型推断的请求方法
const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  return http(config);
};

// 添加请求方法
request.get = <T = any>(url: string, config?: AxiosRequestConfig) => {
  return request<T>({ ...config, method: "get", url });
};

request.post = <T = any>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig,
) => {
  return request<T>({ ...config, method: "post", url, data });
};

request.put = <T = any>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig,
) => {
  return request<T>({ ...config, method: "put", url, data });
};

request.delete = <T = any>(url: string, config?: AxiosRequestConfig) => {
  return request<T>({ ...config, method: "delete", url });
};

// 导出 request
// 确保导出的是修改后的 request 对象
// 注意：这里导出的是上面添加了方法的 request
// 而不是之前单独定义的函数
// 避免出现类型问题
// 这里直接导出添加方法后的 request
// 而不是单独导出函数
// 确保类型正确
// 避免混淆
// 直接导出修改后的 request
// 这样可以正确使用添加的方法
export { request };

export default http;
